home *** CD-ROM | disk | FTP | other *** search
- /* analform.c 1.9beta -- parse the output of the analog form interface */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- /* You must change the next line to indicate where the analog program lives */
-
- #define COMMAND "/http/cgi-bin/analog"
- #define MAXARGLENGTH (2048) /* should be plenty */
- #define OK (0)
- #define ERR (-1)
- #define STRLENGTH (64)
-
- typedef int flag;
-
- void unhttp(char *url) /* converts back all http special characters */
- {
- char *tempp;
- char tempstr[MAXARGLENGTH];
- int i;
-
- /* firstly, change +'s into spaces */
-
- for (i = strlen(url) - 1; i >= 0; i--) {
- if (url[i] == '+')
- url[i] = ' ';
- }
-
- /* secondly change %7E to ~, etc. */
-
- tempp = url;
- while ((tempp = strchr(tempp, '%')) != NULL) {
- sscanf(tempp + 1, "%2x", &i);
- if (i >= 0x20 && i < 0x7F) {
- *tempp = i;
- strcpy(tempstr, tempp + 3);
- strcpy(tempp + 1, tempstr);
- /* strcpy(tempp + 1, tempp + 3) may not be safe on all machines
- (overlapping arguments) */
- }
- tempp++;
- }
-
- }
-
- void genopts(FILE *thepipe, char name[9], int sortby, char *astr, char *cstr)
- {
- fprintf(thepipe, "%sSORTBY ", name);
- if (sortby == 3)
- fprintf(thepipe, "RANDOM\n");
- else if (sortby == 2)
- fprintf(thepipe, "ALPHABETICAL\n");
- else if (sortby == 1)
- fprintf(thepipe, "BYTES\n");
- else
- fprintf(thepipe, "REQUESTS\n");
- if (sortby == 1) {
- if (cstr[0] != '\0')
- fprintf(thepipe, "%sMINBYTES %s\n", name, cstr);
- }
- else {
- if (astr[0] != '\0')
- fprintf(thepipe, "%sMINREQS %s\n", name, astr);
- }
- }
-
- int main()
- {
- extern void exit();
-
- /* the input */
- char *argstring;
- char *nextarg;
- char *nextval;
-
- /* the variables that can be read in */
- int xq = 0, mq = 0, Wq = 0, dq = 0, Dq = 0, hq = 0, oq = 0, Sq = 0;
- int iq = 0, rq = 0, fq = 0, bq = 0, Bq = 0, cq = 0, eq = 0, Hq = 0;
- char mg = '\0', Wg = '\0', dg = '\0', Dg = '\0', hg = '\0', Hg = '\0';
- int os, Ss, is, rs, fs, Bs, bs;
- int ou = 0;
- char oa[STRLENGTH], Sa[STRLENGTH], ia[STRLENGTH], ra[STRLENGTH];
- char fa[STRLENGTH], Ba[STRLENGTH], ba[STRLENGTH];
- char oc[STRLENGTH], Sc[STRLENGTH], ic[STRLENGTH], rc[STRLENGTH];
- char fc[STRLENGTH], Bc[STRLENGTH], bc[STRLENGTH];
- int dirlevel;
- char reqtype, reqlinks;
- char *from = NULL, *to = NULL;
- char *fonly = NULL, *fign = NULL;
- char *honly = NULL, *hign = NULL;
- char *org = NULL, *home = NULL;
- char *logfile, *reflog, *browlog, *errlog, *cachefile;
- char *TZ = NULL;
- char TZenv[STRLENGTH];
-
- FILE *thepipe;
- int ret;
-
- oa[0] = '\0';
- Sa[0] = '\0';
- ia[0] = '\0';
- ra[0] = '\0';
- fa[0] = '\0';
- ba[0] = '\0';
- Ba[0] = '\0';
- oc[0] = '\0';
- Sc[0] = '\0';
- ic[0] = '\0';
- rc[0] = '\0';
- fc[0] = '\0';
- bc[0] = '\0';
- Bc[0] = '\0';
-
- if ((argstring = getenv("QUERY_STRING")) == NULL) {
- printf("Content-type: text/plain\n\n");
- printf("Error: cannot find environment variable QUERY_STRING\n");
- exit(ERR);
- }
-
- unhttp(argstring);
-
- nextarg = strtok(argstring, "&");
-
- while (nextarg != NULL) {
- nextval = strchr(nextarg, '=') + 1;
- if (nextval[0] != '\0') {
- switch(nextarg[0]) {
- case 'b':
- switch(nextarg[1]) {
- case 'a':
- strcpy(ba, nextval);
- break;
- case 'b':
- strcpy(ba, "-");
- strcat(ba, nextval);
- break;
- case 'c':
- strcpy(bc, nextval);
- break;
- case 'd':
- strcpy(bc, "-");
- strcat(bc, nextval);
- break;
- case 'q':
- bq = atoi(nextval);
- break;
- case 's':
- bs = atoi(nextval);
- break;
- }
- break;
- case 'B':
- switch(nextarg[1]) {
- case 'a':
- strcpy(Ba, nextval);
- break;
- case 'b':
- strcpy(ba, "-");
- strcat(ba, nextval);
- break;
- case 'c':
- strcpy(Bc, nextval);
- break;
- case 'd':
- strcpy(Bc, "-");
- strcat(Bc, nextval);
- break;
- case 'q':
- Bq = atoi(nextval);
- break;
- case 's':
- Bs = atoi(nextval);
- break;
- }
- break;
- case 'c':
- cq = atoi(nextval);
- break;
- case 'd':
- switch(nextarg[1]) {
- case 'g':
- dg = nextval[0];
- break;
- case 'q':
- dq = 1;
- break;
- }
- break;
- case 'D':
- switch(nextarg[1]) {
- case 'g':
- Dg = nextval[0];
- break;
- case 'q':
- Dq = 1;
- break;
- }
- break;
- case 'e':
- eq = atoi(nextval);
- break;
- case 'f':
- switch(nextarg[1]) {
- case 'a':
- strcpy(fa, nextval);
- break;
- case 'b':
- strcpy(fa, "-");
- strcat(fa, nextval);
- break;
- case 'c':
- strcpy(fc, nextval);
- break;
- case 'd':
- strcpy(fc, "-");
- strcat(fc, nextval);
- break;
- case 'i':
- fign = nextval;
- break;
- case 'q':
- fq = atoi(nextval);
- break;
- case 'r':
- from = nextval;
- break;
- case 's':
- fs = atoi(nextval);
- break;
- case 'y':
- fonly = nextval;
- break;
- }
- break;
- case 'h':
- switch(nextarg[1]) {
- case 'g':
- hg = nextval[0];
- break;
- case 'i':
- hign = nextval;
- break;
- case 'o':
- home = nextval;
- break;
- case 'q':
- hq = 1;
- break;
- case 'y':
- honly = nextval;
- break;
- }
- break;
- case 'H':
- switch(nextarg[1]) {
- case 'g':
- Hg = nextval[0];
- break;
- case 'q':
- Hq = atoi(nextval);
- break;
- }
- break;
- case 'i':
- switch(nextarg[1]) {
- case 'a':
- strcpy(ia, nextval);
- break;
- case 'b':
- strcpy(ia, "-");
- strcat(ia, nextval);
- break;
- case 'c':
- strcpy(ic, nextval);
- break;
- case 'd':
- strcpy(ic, "-");
- strcat(ic, nextval);
- break;
- case 'e':
- dirlevel = atoi(nextval);
- break;
- case 'q':
- iq = atoi(nextval);
- break;
- case 's':
- is = atoi(nextval);
- break;
- }
- break;
- case 'l':
- switch(nextarg[1]) {
- case 'b':
- browlog = nextval;
- break;
- case 'c':
- cachefile = nextval;
- break;
- case 'e':
- errlog = nextval;
- break;
- case 'f':
- reflog = nextval;
- break;
- case 'o':
- logfile = nextval;
- break;
- }
- break;
- case 'm':
- switch(nextarg[1]) {
- case 'g':
- mg = nextval[0];
- break;
- case 'q':
- mq = 1;
- break;
- }
- break;
- case 'o':
- switch(nextarg[1]) {
- case 'a':
- strcpy(oa, nextval);
- break;
- case 'b':
- strcpy(oa, "-");
- strcat(oa, nextval);
- break;
- case 'c':
- strcpy(oc, nextval);
- break;
- case 'd':
- strcpy(oc, "-");
- strcat(oc, nextval);
- break;
- case 'q':
- oq = atoi(nextval);
- break;
- case 'r':
- org = nextval;
- break;
- case 's':
- os = atoi(nextval);
- break;
- case 'u':
- ou = atoi(nextval);
- break;
- }
- break;
- case 'r':
- switch(nextarg[1]) {
- case 'a':
- strcpy(ra, nextval);
- break;
- case 'b':
- strcpy(ra, "-");
- strcat(ra, nextval);
- break;
- case 'c':
- strcpy(rc, nextval);
- break;
- case 'd':
- strcpy(rc, "-");
- strcat(rc, nextval);
- break;
- case 'l':
- reqlinks = nextval[0];
- break;
- case 'q':
- rq = atoi(nextval);
- break;
- case 's':
- rs = atoi(nextval);
- break;
- case 't':
- reqtype = nextval[0];
- break;
- }
- break;
- case 'S':
- switch(nextarg[1]) {
- case 'a':
- strcpy(Sa, nextval);
- break;
- case 'b':
- strcpy(Sa, "-");
- strcat(Sa, nextval);
- break;
- case 'c':
- strcpy(Sc, nextval);
- break;
- case 'd':
- strcpy(Sc, "-");
- strcat(Sc, nextval);
- break;
- case 'q':
- Sq = atoi(nextval);
- break;
- case 's':
- Ss = atoi(nextval);
- break;
- }
- break;
- case 't':
- to = nextval;
- break;
- case 'T':
- TZ = nextval;
- break;
- case 'W':
- switch(nextarg[1]) {
- case 'g':
- Wg = nextval[0];
- break;
- case 'q':
- Wq = 1;
- break;
- }
- break;
- case 'x':
- xq = 1;
- break;
- }
- }
- nextarg = strtok((char *)NULL, "&");
- }
-
- /* OK, so we've read everything in, now send it to the program */
-
- if (TZ != NULL) {
- strcpy(TZenv, "TZ=");
- strcat(TZenv, TZ);
- putenv(TZenv);
- }
-
- if ((thepipe = popen(COMMAND " +g-", "w")) == NULL) {
- printf("Content-type: text/plain\n\n");
- printf("Error: cannot start analog program at %s\n", COMMAND);
- }
-
- else {
- printf("Content-type: text/html\n\n");
- fflush(stdout);
-
- fprintf(thepipe, "OUTFILE stdout\n");
-
- if (xq < 2)
- fprintf(thepipe, "GENERAL %s\n", xq?"ON":"OFF");
- if (mq < 2)
- fprintf(thepipe, "MONTHLY %s\n", mq?"ON":"OFF");
- if (Wq < 2)
- fprintf(thepipe, "WEEKLY %s\n", Wq?"ON":"OFF");
- if (dq < 2)
- fprintf(thepipe, "DAILY %s\n", dq?"ON":"OFF");
- if (Dq < 2)
- fprintf(thepipe, "FULLDAILY %s\n", Dq?"ON":"OFF");
- if (hq < 2)
- fprintf(thepipe, "HOURLY %s\n", hq?"ON":"OFF");
- if (Hq < 2)
- fprintf(thepipe, "FULLHOURLY %s\n", Hq?"ON":"OFF");
- if (oq < 2)
- fprintf(thepipe, "DOMAIN %s\n", oq?"ON":"OFF");
- if (Sq < 2)
- fprintf(thepipe, "FULLHOSTS %s\n", Sq?"ON":"OFF");
- if (iq < 2)
- fprintf(thepipe, "DIRECTORY %s\n", iq?"ON":"OFF");
- if (rq < 2)
- fprintf(thepipe, "REQUEST %s\n", rq?"ON":"OFF");
- if (bq < 2)
- fprintf(thepipe, "BROWSER %s\n", bq?"ON":"OFF");
- if (Bq < 2)
- fprintf(thepipe, "FULLBROWSER %s\n", Bq?"ON":"OFF");
- if (cq < 2)
- fprintf(thepipe, "STATUS %s\n", bq?"ON":"OFF");
- if (eq < 2)
- fprintf(thepipe, "ERROR %s\n", bq?"ON":"OFF");
- if (fq < 2)
- fprintf(thepipe, "REFERER %s\n", bq?"ON":"OFF");
-
- if (mq && mg != '\0')
- fprintf(thepipe, "MONTHGRAPH %c", mg);
- if (Wq && Wg != '\0')
- fprintf(thepipe, "WEEKGRAPH %c", Wg);
- if (hq && hg != '\0')
- fprintf(thepipe, "HOURGRAPH %c", hg);
- if (Hq && Hg != '\0')
- fprintf(thepipe, "FULLHOURGRAPH %c", Hg);
- if (dq && dg != '\0')
- fprintf(thepipe, "DAYGRAPH %c", dg);
- if (Dq && Dg != '\0')
- fprintf(thepipe, "FULLDAYGRAPH %c", Dg);
-
- if (oq)
- genopts(thepipe, "DOM", os, oa, oc);
- if (Sq)
- genopts(thepipe, "HOST", Ss, Sa, Sc);
- if (iq) {
- genopts(thepipe, "DIR", is, ia, ic);
- fprintf(thepipe, "DIRLEVEL %d\n", dirlevel);
- }
- if (rq) {
- genopts(thepipe, "REQ", rs, ra, rc);
- fprintf(thepipe, "REQTYPE %s\n", reqtype=='f'?"ALL":"PAGES");
- fprintf(thepipe, "PAGELINKS %s\n", reqlinks=='f'?"ALL":(reqlinks=='p'?"ON":"OFF"));
- }
- if (bq)
- genopts(thepipe, "BROW", bs, ba, bc);
- if (Bq)
- genopts(thepipe, "FULLBROW", Bs, Ba, Bc);
- if (fq)
- genopts(thepipe, "REF", fs, fa, fc);
-
- fprintf(thepipe, "OUTPUT %s\n", ou?"ASCII":"HTML");
-
- if (from != NULL)
- fprintf(thepipe, "FROM %s\n", from);
- if (to != NULL)
- fprintf(thepipe, "TO %s\n", to);
- if (org != NULL)
- fprintf(thepipe, "HOSTNAME \"%s\"\n", org);
- if (home != NULL)
- fprintf(thepipe, "HOSTURL %s\n", home);
- else
- fprintf(thepipe, "HOSTURL -\n");
-
- /* That just leaves the only's and ignore's and logfiles, which are a bit
- more complicated as we have to parse them still. Recycle 'nextarg'. */
-
- nextarg = strtok(fonly, " ,"); /* split at spaces and commas */
- while (nextarg != NULL) {
- fprintf(thepipe, "FILEINCLUDE %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- nextarg = strtok(fign, " ,");
- while (nextarg != NULL) {
- fprintf(thepipe, "FILEEXCLUDE %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- nextarg = strtok(honly, " ,");
- while (nextarg != NULL) {
- fprintf(thepipe, "HOSTINCLUDE %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- nextarg = strtok(hign, " ,");
- while (nextarg != NULL) {
- fprintf(thepipe, "HOSTEXCLUDE %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- nextarg = strtok(browlog, " ,");
- while (nextarg != NULL) {
- fprintf(thepipe, "BROWLOG %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- nextarg = strtok(errlog, " ,");
- while (nextarg != NULL) {
- fprintf(thepipe, "ERRLOG %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- nextarg = strtok(reflog, " ,");
- while (nextarg != NULL) {
- fprintf(thepipe, "REFLOG %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- nextarg = strtok(logfile, " ,");
- while (nextarg != NULL) {
- fprintf(thepipe, "LOGFILE %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- nextarg = strtok(cachefile, " ,");
- while (nextarg != NULL) {
- fprintf(thepipe, "CACHEFILE %s\n", nextarg);
- nextarg = strtok((char *)NULL, " ,");
- }
-
- }
-
- fflush(thepipe);
- ret = pclose(thepipe);
- if (ret != 0) {
- printf("Analog failed to run or returned an error code.\n");
- printf("Maybe your server's error log will give a clue why.\n");
- }
- fflush(stdout);
- exit(ret);
-
- }
- extern int putenv(char *newval)
- {
- extern char **environ;
-
- static int firstTime = 1;
- char **ep;
- char *cp;
- int esiz;
- char *np;
-
- if (!(np = strchr(newval, '=')))
- return 1;
- *np = '\0';
-
- /* look it up */
- for (ep=environ ; *ep ; ep++)
- {
- /* this should always be true... */
- if (cp = strchr(*ep, '='))
- {
- *cp = '\0';
- if (!strcmp(*ep, newval))
- {
- /* got it! */
- *cp = '=';
- break;
- }
- *cp = '=';
- }
- else
- {
- *np = '=';
- return 1;
- }
- }
-
- *np = '=';
- if (*ep)
- {
- /* the string was already there: just replace it with the new one */
- *ep = newval;
- return 0;
- }
-
- /* expand environ by one */
- for (esiz=2, ep=environ ; *ep ; ep++)
- esiz++;
- if (firstTime)
- {
- char **epp;
- char **newenv;
- if (!(newenv = malloc(esiz * sizeof(char *))))
- return 1;
-
- for (ep=environ, epp=newenv ; *ep ;)
- *epp++ = *ep++;
- *epp++ = newval;
- *epp = (char *) 0;
- environ = newenv;
- }
- else
- {
- if (!(environ = realloc(environ, esiz * sizeof(char *))))
- return 1;
- environ[esiz - 2] = newval;
- environ[esiz - 1] = (char *) 0;
- firstTime = 0;
- }
-
- return 0;
- }
-